home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / access / nobtree / nobtscan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  4.1 KB  |  171 lines

  1. /*
  2.  *  btscan.c -- manage scans on btrees.
  3.  *
  4.  *    Because we can be doing an index scan on a relation while we update
  5.  *    it, we need to avoid missing data that moves around in the index.
  6.  *    The routines and global variables in this file guarantee that all
  7.  *    scans in the local address space stay correctly positioned.  This
  8.  *    is all we need to worry about, since write locking guarantees that
  9.  *    no one else will be on the same page at the same time as we are.
  10.  *
  11.  *    The scheme is to manage a list of active scans in the current backend.
  12.  *    Whenever we add or remove records from an index, or whenever we
  13.  *    split a leaf page, we check the list of active scans to see if any
  14.  *    has been affected.  A scan is affected only if it is on the same
  15.  *    relation, and the same page, as the update.
  16.  */
  17.  
  18. #include "tmp/c.h"
  19.  
  20. #ifdef NOBTREE
  21. #include "tmp/postgres.h"
  22.  
  23. #include "storage/bufmgr.h"
  24. #include "storage/bufpage.h"
  25. #include "storage/page.h"
  26.  
  27. #include "utils/log.h"
  28. #include "utils/rel.h"
  29. #include "utils/excid.h"
  30.  
  31. #include "access/heapam.h"
  32. #include "access/genam.h"
  33. #include "access/sdir.h"
  34. #include "access/nobtree.h"
  35.  
  36. RcsId("$Header: /private/postgres/src/access/nobtree/RCS/nobtscan.c,v 1.6 1991/06/26 19:12:14 mao Exp $");
  37.  
  38. typedef struct BTScanListData {
  39.     IndexScanDesc        btsl_scan;
  40.     struct BTScanListData    *btsl_next;
  41. } BTScanListData;
  42.  
  43. typedef BTScanListData    *BTScanList;
  44.  
  45. static BTScanList    BTScans = (BTScanList) NULL;
  46.  
  47. /*
  48.  *  _nobt_regscan() -- register a new scan.
  49.  */
  50.  
  51. void
  52. _nobt_regscan(scan)
  53.     IndexScanDesc scan;
  54. {
  55.     BTScanList new_el;
  56.  
  57.     new_el = (BTScanList) palloc(sizeof(BTScanListData));
  58.     new_el->btsl_scan = scan;
  59.     new_el->btsl_next = BTScans;
  60.     BTScans = new_el;
  61. }
  62.  
  63. /*
  64.  *  _nobt_dropscan() -- drop a scan from the scan list
  65.  */
  66.  
  67. void
  68. _nobt_dropscan(scan)
  69.     IndexScanDesc scan;
  70. {
  71.     BTScanList chk, last;
  72.  
  73.     last = (BTScanList) NULL;
  74.     for (chk = BTScans;
  75.      chk != (BTScanList) NULL && chk->btsl_scan != scan;
  76.      chk = chk->btsl_next) {
  77.     last = chk;
  78.     }
  79.  
  80.     if (chk == (BTScanList) NULL)
  81.     elog(WARN, "btree scan list trashed; can't find 0x%lx", scan);
  82.  
  83.     if (last == (BTScanList) NULL)
  84.     BTScans = chk->btsl_next;
  85.     else
  86.     last->btsl_next = chk->btsl_next;
  87.  
  88.     pfree (chk);
  89. }
  90.  
  91. void
  92. _nobt_adjscans(rel, tid)
  93.     Relation rel;
  94.     ItemPointer tid;
  95. {
  96.     BTScanList l;
  97.     ObjectId relid, chkrelid;
  98.  
  99.     relid = rel->rd_id;
  100.     for (l = BTScans; l != (BTScanList) NULL; l = l->btsl_next) {
  101.     if (relid == l->btsl_scan->relation->rd_id)
  102.         _nobt_scandel(l->btsl_scan, ItemPointerGetBlockNumber(tid),
  103.             ItemPointerGetOffsetNumber(tid, 0));
  104.     }
  105. }
  106.  
  107. void
  108. _nobt_scandel(scan, blkno, offno)
  109.     IndexScanDesc scan;
  110.     BlockNumber blkno;
  111.     OffsetNumber offno;
  112. {
  113.     ItemPointer current;
  114.     Buffer buf;
  115.     NOBTScanOpaque so;
  116.  
  117.     if (!_nobt_scantouched(scan, blkno, offno))
  118.     return;
  119.  
  120.     so = (NOBTScanOpaque) scan->opaque;
  121.     buf = so->nobtso_curbuf;
  122.  
  123.     current = &(scan->currentItemData);
  124.     if (ItemPointerIsValid(current)
  125.     && ItemPointerGetBlockNumber(current) == blkno
  126.     && ItemPointerGetOffsetNumber(current, 0) >= offno) {
  127.     _nobt_step(scan, &buf, BackwardScanDirection);
  128.     so->nobtso_curbuf = buf;
  129.     }
  130.  
  131.     current = &(scan->currentMarkData);
  132.     if (ItemPointerIsValid(current)
  133.     && ItemPointerGetBlockNumber(current) == blkno
  134.     && ItemPointerGetOffsetNumber(current, 0) >= offno) {
  135.     ItemPointerData tmp;
  136.     tmp = *current;
  137.     *current = scan->currentItemData;
  138.     scan->currentItemData = tmp;
  139.     _nobt_step(scan, &buf, BackwardScanDirection);
  140.     so->nobtso_mrkbuf = buf;
  141.     tmp = *current;
  142.     *current = scan->currentItemData;
  143.     scan->currentItemData = tmp;
  144.     }
  145. }
  146.  
  147. bool
  148. _nobt_scantouched(scan, blkno, offno)
  149.     IndexScanDesc scan;
  150.     BlockNumber blkno;
  151.     OffsetNumber offno;
  152. {
  153.     ItemPointer current;
  154.  
  155.     current = &(scan->currentItemData);
  156.     if (ItemPointerIsValid(current)
  157.     && ItemPointerGetBlockNumber(current) == blkno
  158.     && ItemPointerGetOffsetNumber(current, 0) >= offno)
  159.     return (true);
  160.  
  161.     current = &(scan->currentMarkData);
  162.     if (ItemPointerIsValid(current)
  163.     && ItemPointerGetBlockNumber(current) == blkno
  164.     && ItemPointerGetOffsetNumber(current, 0) >= offno)
  165.     return (true);
  166.  
  167.     return (false);
  168. }
  169.  
  170. #endif /* NOBTREE */
  171.